Skip to content

feat(rest): support query auth for REST catalog tables - #534

Open
SteNicholas wants to merge 1 commit into
apache:mainfrom
SteNicholas:PAIMON-520
Open

SteNicholas wants to merge 1 commit into
apache:mainfrom
SteNicholas:PAIMON-520

Conversation

@SteNicholas

@SteNicholas SteNicholas commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Purpose

Linked issue: close #520

A REST catalog can restrict what a query on a table with query-auth.enabled=true returns, through row filters and column masks. This PR fetches those rules from the catalog at plan time, carries them on each split, and applies them when the split is read. Read paths that would bypass the rules are refused.

Catalog

  • RestCatalog implements QueryAuthCatalog::AuthTableQuery on POST /v1/{prefix}/databases/{database}/tables/{table}/auth, using the new AuthTableQueryRequest and AuthTableQueryResponse messages. External tables get no rules.
  • TableQueryAuthResult parses the rule JSON into a row filter and NULL, FIELD_REF, CONCAT, CONCAT_WS and SUBSTRING masks. It refuses malformed or unsupported rules and validates them against a schema by column name, type and field id.

Scan and read

  • QueryAuthTableScan fetches and validates the rules on every plan, pushes down only the row filter and the predicate conjuncts on unmasked columns, and wraps each split in a QueryAuthSplit.
  • QueryAuthTableRead applies the row filter, then the masks, then the read predicate. It refuses a split whose authorized columns no longer match the schema being read.
  • QueryAuthSplit serializes with the field ids its rules were authorized for.
  • TableScan::Create and TableRead::Create turn query auth on from the catalog's schema for the branch read, and refuse search, explicit read schemas, real-time and fallback reads, global index scans, and the $files, $binlog, $audit_log and $ro system tables.

Other

  • Adds ScanContextBuilder::SetReadFieldNames(). The scan and read context builders now carry the branch option into the catalog identifier.
  • In LIKE, _ now matches any character, including a line terminator.

Tests

  • Rules: TableQueryAuthResultTest.* covers rule parsing, literal types and boundaries, constant folding, masks, schema and field-id validation, and malformed or unsupported rules.
  • Splits: QueryAuthSplitTest.* covers deserializing the fixtures under test/test_data/query_auth/, round trips, and malformed bytes.
  • Read: QueryAuthTableReadTest.* covers dictionary and large-string decoding, and closing readers when a split fails.
  • End to end: TableTest.TestQueryAuth* plans and reads through a mock query-auth catalog, covering branches, schema changes, pruning and limit pushdown, primary-key, deletion-vector and data-evolution tables, and refused read paths.
  • REST: RestCatalogTest.*QueryAuth*, RestCatalogTest.AuthTableQuery*, RestApiTest.AuthTableQuery, RestMessagesTest.AuthTableQuery* and ResourcePathsTest.* cover the endpoint, the messages, retries and error mapping.
  • Supporting changes: ScanContextTest.TestWithCatalogResolvesTheBranch, ReadContextTest.TestWithCatalogResolvesTheBranch, SchemaValidationTest.TestQueryAuth, FormatTableTest.TestQueryAuthInTheSchemaCannotBeDisabledAtTheCall, PredicateTest.TestLikeWildcardsMatchLineTerminators, RapidJsonUtilTest.TestRejectUnescapedNul, RapidJsonUtilTest.TestSerializeStringWithEmbeddedNul, RapidJsonUtilTest.TestCheckNoDuplicateMembers, DataTypeJsonParserTest.ParseTypeRejectsEmbeddedNul, CoreOptionsTest.TestDefaultValue and CoreOptionsTest.TestFromMap.
  • Integration: the BlobTableInteTest cases that read a missing upstream table now expect NotExist.

API and Format

  • Public API: adds Options::QUERY_AUTH_ENABLED (query-auth.enabled), ScanContextBuilder::SetReadFieldNames(), ScanContext::GetReadFieldNames() and a ScanContext constructor that takes the read field names. Updates the WithCatalog() docs of both context builders.
  • Split serialization: a split of a query-auth table serializes as a QueryAuthSplit together with its authorized field ids. Other splits, and the table's data and metadata files, are unchanged.
  • Protocol: the REST catalog calls POST .../tables/{table}/auth.

Documentation

docs/source/user_guide/catalog.rst documents the option, the supported rules, how a query-auth table is planned and read, the refused read paths, and the limits of query-auth splits across runtimes.

Generative AI tooling

Generated-by: Claude Code (2.1.311, Claude Opus 5.5)

🤖 Generated with Claude Code

@SteNicholas
SteNicholas force-pushed the PAIMON-520 branch 3 times, most recently from ec531b4 to b0fb5cd Compare November 6, 2026 20:06
Enforce the row filters and column masks a REST catalog defines for
tables with `query-auth.enabled=true`.

- RestCatalog: implement `QueryAuthCatalog::AuthTableQuery` against
  `POST .../tables/{table}/auth`, with new `AuthTableQueryRequest` and
  `AuthTableQueryResponse` messages. External tables get no rules.
- TableQueryAuthResult: parse the predicate and transform JSON into a
  row filter and NULL, FIELD_REF, CONCAT, CONCAT_WS and SUBSTRING
  masks, refuse malformed or unsupported rules, and validate them
  against a schema by column name, type and field id.
- QueryAuthTableScan: fetch and validate the rules on every plan, push
  down only the row filter and the predicate conjuncts on unmasked
  columns, and wrap each split in a `QueryAuthSplit`.
- QueryAuthTableRead: apply the row filter, then the masks, then the
  read predicate, and refuse a split whose authorized columns no
  longer match the schema read.
- Split: serialize `QueryAuthSplit` with the field ids its rules were
  authorized for.
- TableScan/TableRead: enable query auth from the catalog's branch
  schema, and refuse paths that would bypass the rules: search,
  explicit read schemas, real-time and fallback reads, global index
  scans and the $files, $binlog, $audit_log and $ro system tables.
- ScanContextBuilder: add `SetReadFieldNames`; the scan and read
  context builders carry the `branch` option into the catalog
  identifier.
- Like: let `_` match any character, including a line terminator.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Support query auth for REST catalog

1 participant